-
Notifications
You must be signed in to change notification settings - Fork 2.5k
fix: persist and restore active task on VS Code restart #7660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add currentActiveTaskId to global settings schema - Persist task ID when adding/removing tasks from stack - Restore last active task in resolveWebviewView on startup - Add comprehensive tests for task persistence functionality Fixes #7659
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed my own code. Found it acceptable. Mostly.
| } else { | ||
| // Update to the new top task | ||
| const newCurrentTask = this.clineStack[this.clineStack.length - 1] | ||
| await this.updateGlobalState("currentActiveTaskId", newCurrentTask.taskId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this intentional? There's a potential race condition here between checking the stack length and updating the task ID. If another operation modifies the stack between lines 425 and 430, we might update to the wrong task ID. Consider using a lock or making this operation atomic.
| await this.removeClineFromStack() | ||
|
|
||
| // Attempt to restore the last active task if one was persisted | ||
| const lastActiveTaskId = this.getGlobalState("currentActiveTaskId") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The task restoration logic could benefit from explicit cleanup if restoration fails partway through. Consider wrapping this in a try-finally block to ensure any partially initialized resources are properly released on error:
| const lastActiveTaskId = this.getGlobalState("currentActiveTaskId") | |
| const lastActiveTaskId = this.getGlobalState("currentActiveTaskId") | |
| if (lastActiveTaskId && typeof lastActiveTaskId === "string") { | |
| let partiallyRestoredTask = null | |
| try { | |
| const { historyItem } = await this.getTaskWithId(lastActiveTaskId) | |
| if (historyItem) { | |
| partiallyRestoredTask = await this.createTaskWithHistoryItem(historyItem) | |
| this.log(`Restored last active task: ${lastActiveTaskId}`) | |
| } | |
| } catch (error) { | |
| // Task may have been deleted or corrupted, clear the saved ID | |
| this.log(`Failed to restore last active task ${lastActiveTaskId}: ${error}`) | |
| await this.updateGlobalState("currentActiveTaskId", undefined) | |
| } finally { | |
| // Clean up any partially restored task if needed | |
| if (partiallyRestoredTask && this.clineStack.length === 0) { | |
| // Cleanup logic here if needed | |
| } | |
| } | |
| } |
| lastShownAnnouncementId: z.string().optional(), | ||
| customInstructions: z.string().optional(), | ||
| taskHistory: z.array(historyItemSchema).optional(), | ||
| currentActiveTaskId: z.string().optional(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a more descriptive JSDoc comment here? Something like:
| currentActiveTaskId: z.string().optional(), | |
| /** | |
| * The ID of the currently active task that should be restored when VS Code restarts. | |
| * This ensures chat context persistence across unexpected crashes or restarts. | |
| * @since 3.26.7 | |
| */ | |
| currentActiveTaskId: z.string().optional(), |
| } | ||
| } catch (error) { | ||
| // Task may have been deleted or corrupted, clear the saved ID | ||
| this.log(`Failed to restore last active task ${lastActiveTaskId}: ${error}`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding more detailed logging here for debugging purposes. Including task details in the error log would help diagnose restoration issues:
| this.log(`Failed to restore last active task ${lastActiveTaskId}: ${error}`) | |
| // Task may have been deleted or corrupted, clear the saved ID | |
| this.log(`Failed to restore last active task ${lastActiveTaskId}: ${error instanceof Error ? error.message : String(error)}`) | |
| this.log(`Task restoration error details: ${JSON.stringify({ taskId: lastActiveTaskId, error: error instanceof Error ? { message: error.message, stack: error.stack } : error })}`) | |
| await this.updateGlobalState("currentActiveTaskId", undefined) |
|
Closing, see #7659 (comment) |
Description
This PR fixes issue #7659 where Roo Code loses chat context when VS Code unexpectedly crashes or needs to be restarted. The last active chat now persists and automatically restores when VS Code restarts.
Problem
Solution
currentActiveTaskIdfield to global settings schema to track the active taskChanges
currentActiveTaskIdfield to schemaaddClineToStack()andremoveClineFromStack()resolveWebviewView()Testing
Related Issues
Fixes #7659
Checklist
Important
This PR fixes task context loss on VS Code restart by persisting and restoring the active task ID, with changes in
global-settings.tsandClineProvider.ts, and adds comprehensive tests.currentActiveTaskIdtoglobalSettingsSchemainglobal-settings.tsto track active task.addClineToStack()andremoveClineFromStack()inClineProvider.ts.resolveWebviewView()inClineProvider.ts.ClineProvider.spec.tsfor task persistence and restoration.This description was created by
for e9fa2a6. You can customize this summary. It will automatically update as commits are pushed.